#ifndef __style_h__
#define __style_h__

#include "define.h"
#include <string>
#include "functor.h"
#include "../xml/xml.h"
#include "../tool/base.h"
#include "../tool/tstring.h"

#include <map>



namespace core
{



/*
 * @breif: property name define.
 */
extern const char * STYLE_PROPERTY_BACKGROUND;
extern const char * STYLE_PROPERTY_BACKGROUND_COLOR;
extern const char * STYLE_PROPERTY_BACKGROUND_IMAGE;
extern const char * STYLE_PROPERTY_BACKGROUND_REPEAT;
extern const char * STYLE_PROPERTY_COLOR;
extern const char * STYLE_PROPERTY_LINE_HEIGHT;
extern const char * STYLE_PROPERTY_HORIZONTAL_ALIGN;
extern const char * STYLE_PROPERTY_VERTICAL_ALIGN;
extern const char * STYLE_PROPERTY_TEXT_ALIGN;
extern const char * STYLE_PROPERTY_UNDERLINE;
extern const char * STYLE_PROPERTY_TEXT_INDENT;
extern const char * STYLE_PROPERTY_FONT;
extern const char * STYLE_PROPERTY_FONT_FAMILY;
extern const char * STYLE_PROPERTY_FONT_SIZE;
extern const char * STYLE_PROPERTY_FONT_STYLE;
extern const char * STYLE_PROPERTY_BORDER;
extern const char * STYLE_PROPERTY_BORDER_WIDTH;
extern const char * STYLE_PROPERTY_BORDER_STYLE;
extern const char * STYLE_PROPERTY_BORDER_COLOR;
extern const char * STYLE_PROPERTY_POSITION;
extern const char * STYLE_PROPERTY_MARGIN;
extern const char * STYLE_PROPERTY_MARGIN_LEFT;
extern const char * STYLE_PROPERTY_MARGIN_TOP;
extern const char * STYLE_PROPERTY_MARGIN_RIGHT;
extern const char * STYLE_PROPERTY_MARGIN_BOTTOM;
extern const char * STYLE_PROPERTY_PADDING;
extern const char * STYLE_PROPERTY_PADDING_LEFT;
extern const char * STYLE_PROPERTY_PADDING_TOP;
extern const char * STYLE_PROPERTY_PADDING_RIGHT;
extern const char * STYLE_PROPERTY_PADDING_BOTTOM;
extern const char * STYLE_PROPERTY_LEFT;
extern const char * STYLE_PROPERTY_TOP;
extern const char * STYLE_PROPERTY_RIGHT;
extern const char * STYLE_PROPERTY_BOTTOM;
extern const char * STYLE_PROPERTY_WIDTH;
extern const char * STYLE_PROPERTY_HEIGHT;
extern const char * STYLE_PROPERTY_CURSOR;





/*
 * @breif: face style object.
 */
class FaceStyle
    : public FaceObject
{
public:
    FaceStyle();

    enum PropertyType
    {
        PROPERTY_BACKGROUND_COLOR,
        PROPERTY_BACKGROUND_IMAGE,
        PROPERTY_BACKGROUND_REPEAT,

        PROPERTY_TEXT_COLOR,
        PROPERTY_LINE_HEIGHT,
        PROPERTY_HORIZONTAL_ALIGNMENT,
        PROPERTY_VERTICAL_ALIGNMENT,
        PROPERTY_TEXT_ALIGNMENT,
        PROPERTY_UNDERLINE,
        PROPERTY_TEXT_INDENT,

        PROPERTY_FONT_FAMILY,
        PROPERTY_FONT_SIZE,
        PROPERTY_FONT_STYLE,

        PROPERTY_BORDER_WIDTH,
        PROPERTY_BORDER_STYLE,
        PROPERTY_BORDER_COLOR,

        PROPERTY_POSITION,

        PROPERTY_MARGIN_LEFT,
        PROPERTY_MARGIN_TOP,
        PROPERTY_MARGIN_RIGHT,
        PROPERTY_MARGIN_BOTTOM,

        PROPERTY_PADDING_LEFT,
        PROPERTY_PADDING_TOP,
        PROPERTY_PADDING_RIGHT,
        PROPERTY_PADDING_BOTTOM,

        PROPERTY_LEFT,
        PROPERTY_TOP,
        PROPERTY_RIGHT,
        PROPERTY_BOTTOM,

        PROPERTY_WIDTH,
        PROPERTY_HEIGHT,

        PROPERTY_CURSOR_TYPE,

        PROPERTY_MAX
    };

    enum StyleType
    {
        STYLE_NAME,
        STYLE_CLASS,
        STYLE_ID
    };

public:
    color            background_color_;
    std::wstring     background_image_;
    dword            background_repeat_;

    color            text_color_;
    int              line_height_;
    dword            horizontal_alignment_;
    dword            vertical_alignment_;
    dword            text_alignment_;
    bool             underline_;
    int              text_indent_;

    std::wstring     font_family_;
    unit             font_size_;
    dword            font_style_;

    int              border_width_;
    dword            border_style_;
    color            border_color_;

    dword            position_;

    unit             margin_left_;
    unit             margin_top_;
    unit             margin_right_;
    unit             margin_bottom_;

    unit             padding_left_;
    unit             padding_top_;
    unit             padding_right_;
    unit             padding_bottom_;

    unit             left_;
    unit             top_;
    unit             right_;
    unit             bottom_;

    unit             width_;
    unit             height_;

    dword            cursor_type_;

public:
    virtual FaceObjectTrait Trait()                 { return FACE_OBJECT_TRAIT_STYLE; }

    void Init();

    PropertyType Property( const char * property ) const;
    std::string  Property( PropertyType type ) const;

    bool Default( PropertyType type ) const;
    bool Default( const char *property ) const;

    void Copy( const FaceStyle & style, bool cover );
    void Inherit( const FaceStyle & style );

    StyleType Type() const                         { return type_; }
    void SetType( StyleType type )                 { type_ = type; }

    const std::string & Name() const               { return name_; }
    void SetName( const std::string &s )           { name_ = s; }

    const FaceState State() const                  { return state_; }
    void SetState( FaceState state )               { state_ = state; }

    const char * ParseValue ( const char * p );
    void         ParseValues( const char * p );
    const char * ParseStyle ( const char * p );

protected:
    StyleType        type_;
    FaceState        state_;
    std::string      name_;
    bool             default_[ PROPERTY_MAX ];

protected:
    void Copy( PropertyType type, const FaceStyle & style );
    void Inherit( PropertyType type, const FaceStyle & style );

    bool ParseBackground( const char *p );
    bool ParseMargin( const char *p );
    bool ParsePadding( const char *p );
    bool ParseFont( const char *p );
    bool ParseBorder( const char *p );

public:
    DECLARE_ATTRIBUTE_MAP()
};





/*
 * @breif: face style manager.
 */
class FaceStyleManager
{
public:
    FaceStyleManager();

    bool Parse( const char *p );

    bool GetStyleByClass( const std::string& classname, FaceStyle &style, FaceState state = FACE_STATE_NORMAL ) const
    { 
        return get( classname, class_cache_, style, state );
    }

    bool GetStyleById   ( const std::string& id, FaceStyle &style, FaceState state = FACE_STATE_NORMAL ) const
    {
        return get( id, id_cache_, style, state );
    }

    bool GetStyleByName ( const std::string & name, FaceStyle &style, FaceState state = FACE_STATE_NORMAL ) const
    {
        return get( name, name_cache_, style, state );
    }

private:
    struct FaceStyleHolder
    {
        FaceStyle normal_style_;
        FaceStyle *hover_style_;
        FaceStyle *down_style_;
        FaceStyleHolder()
        {
            hover_style_ = 0;
            down_style_  = 0;
        }
    };
    typedef std::map<std::string, FaceStyleHolder> _cache;

private:
    bool get( const std::string &name, const _cache &cache, FaceStyle &style, FaceState state ) const;
    bool save( const std::string &name, _cache &cache, FaceStyle &style );

private:
    _cache class_cache_;
    _cache id_cache_;
    _cache name_cache_;

private:
    DISABLE_COPY_AND_ASSIGN(FaceStyleManager)
};



};
#endif